package org.wx.io.netty.simple;

import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.HexUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.nio.ByteOrder.LITTLE_ENDIAN;

/**
 * @description: serverHandler 处理
 * @author: wangxun
 * @createDate: 2021/2/7
 * @version: 1.0
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        log.info("{} is Active", ctx.channel().remoteAddress());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        Channel channel = ctx.channel();
        log.info("{} is read", channel.remoteAddress());
        ByteBuf byteBuf = (ByteBuf) msg;
        byte first = byteBuf.readByte();
        log.info("first byte is {} ", ByteBufUtil.hexDump(new byte[]{first}));

        int i = byteBuf.readInt();
        int mask = 0xFFFFFFFF;
        int command1 = 0x4039100;
        if (i == (mask & command1)) {

            //  Offs="-40" Gain="1" Unit="℃
            byte MaxT = byteBuf.readByte();
            log.info("最高温度：{} ℃ ", MaxT - 40);
            byte MinT = byteBuf.readByte();
            log.info("最低温度：{} ℃ ", MinT - 40);
            // " Offs="0" Gain="1" Unit="1" >最高温度位置
            //<byte Pos="7" StartBit="4" BitNum="4"></byte>
            //<byte Pos="6" StartBit="0" BitNum="8"></byte>
            byte[] MaxTNo = new byte[2];
            byteBuf.readBytes(MaxTNo);
            byte b7 = MaxTNo[1];
            MaxTNo[1] = (byte) (b7 >> 4);

            log.info("最高温度位置 ：{}", bytesToShort(MaxTNo[1],MaxTNo[0]));

            /**
             * <data Name="MinTNo" Type="0" Save="true" Offs="0" Gain="1" Unit="1" >最低温度位置
             * 			<byte Pos="8" StartBit="0" BitNum="8"></byte>
             * 			<byte Pos="7" StartBit="0" BitNum="4"></byte>
             * 		</data>
             */
            byte b = (byte) (b7 & 0x0F);
            byte b1 = byteBuf.readByte();

            log.info("最低温度位置  ：{}", bytesToShort(b,b1));

            /**
             * <data Name="SOC" Type="0" Save="true" Offs="0" Gain="0.1" Unit="%" >SOC 剩余电量
             * 			<byte Pos="10" StartBit="4" BitNum="4"></byte>
             * 			<byte Pos="9" StartBit="0" BitNum="8"></byte>
             * 		</data>
             */

            byte[] soc = new byte[2];
            byteBuf.readBytes(soc);
            byte b10 = soc[1];

            byte b10_4 = (byte) (b10 >> 4);


            short i1 = bytesToShort(b10_4, soc[0]);
            log.info("SOC 剩余电量  ：{}%", i1 * 0.1);

            /**
             * <data Name="SOH" Type="0" Save="true" Offs="0" Gain="0.1" Unit="%" >SOH 电池健康度
             * 			<byte Pos="11" StartBit="0" BitNum="8"></byte>
             * 			<byte Pos="10" StartBit="0" BitNum="4"></byte>
             * 		</data>
             */
            byte b11 = byteBuf.readByte();

            byte b10_0 = (byte) (soc[1]& 0x0F);

            log.info("SOH 电池健康度 ：{}%", bytesToShort(b10_0,b11) * 0.1);


        }


    }


    short bytesToShort(byte b1,byte b2) {
        byte[] bShrot = new byte[]{b1, b2};
        return ByteUtil.bytesToShort(bShrot, BIG_ENDIAN);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
        Channel channel = ctx.channel();
        log.info("{} is ReadComplete", channel.remoteAddress());
        ctx.writeAndFlush(Unpooled.copiedBuffer("over...", CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
